﻿using Hospital.API.Dto;
using Hospital.API.HospitalServices.IServices;
using Hospital.Domain;
using Hospital.ErrorCode;
using Hospital.Infrastructrue;
using Microsoft.EntityFrameworkCore;

namespace Hospital.API.HospitalServices.Services
{
    public class OrderRecordServices : IOrderRecordServices
    {
        private readonly IBaseRepository<OrderRecord> orderRecordRepository;
        private readonly IBaseRepository<CheckItem> checkItemRepository;
        private readonly IBaseRepository<HospitalBranch> hospitalBranchRepository;
        private readonly IBaseRepository<CheckItemType> checkItemTypeRepository;
        private readonly ILogger<OrderRecordServices> logger;

        public OrderRecordServices(IBaseRepository<OrderRecord> orderRecordRepository, IBaseRepository<CheckItem> checkItemRepository, IBaseRepository<HospitalBranch> hospitalBranchRepository, IBaseRepository<CheckItemType> checkItemTypeRepository, ILogger<OrderRecordServices> logger)
        {
            this.orderRecordRepository = orderRecordRepository;
            this.checkItemRepository = checkItemRepository;
            this.hospitalBranchRepository = hospitalBranchRepository;
            this.checkItemTypeRepository = checkItemTypeRepository;
            this.logger = logger;
        }

        

        /// <summary>
        /// 获取开单记录列表
        /// </summary>
        public async Task<APIResult<APIPaging<List<OrderRecord>>>> GetOrderRecordList(OrderRecordQueryDto queryDto)
        {
            try
            {
                var query = orderRecordRepository.Getlist()
                    .Include(o => o.HospitalBranch)
                    .Include(o => o.CheckItem)
                    .Where(o => !o.IsDeleted);

                // 应用查询条件
                if (!string.IsNullOrEmpty(queryDto.PatientName))
                {
                    query = query.Where(o => o.PatientName.Contains(queryDto.PatientName));
                }

                if (queryDto.HospitalBranchId.HasValue)
                {
                    query = query.Where(o => o.HospitalBranchId == queryDto.HospitalBranchId.Value);
                }

                if (!string.IsNullOrEmpty(queryDto.PaymentStatus) && queryDto.PaymentStatus != "全部")
                {
                    query = query.Where(o => o.PaymentStatus == queryDto.PaymentStatus);
                }

                if (queryDto.StartTime.HasValue)
                {
                    query = query.Where(o => o.OrderTime >= queryDto.StartTime.Value);
                }

                if (queryDto.EndTime.HasValue)
                {
                    query = query.Where(o => o.OrderTime <= queryDto.EndTime.Value);
                }

                // 获取总数
                var totalCount = await query.CountAsync();

                // 分页
                var pageIndex = queryDto.PageIndex <= 0 ? 1 : queryDto.PageIndex;
                var pageSize = queryDto.PageSize <= 0 ? 10 : queryDto.PageSize;
                var totalPages = (int)Math.Ceiling((double)totalCount / pageSize);

                // 获取分页数据
                var orderRecords = await query
                    .OrderByDescending(o => o.OrderTime)
                    .Skip((pageIndex - 1) * pageSize)
                    .Take(pageSize)
                    .ToListAsync();

                var pagingResult = new APIPaging<List<OrderRecord>>
                {
                    TotalCount = totalCount,
                    TotalPages = totalPages,
                    Data = orderRecords
                };

                return new APIResult<APIPaging<List<OrderRecord>>>
                {
                    Code = ResultCode.Success,
                    Message = "获取开单记录列表成功",
                    Data = pagingResult
                };
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "获取开单记录列表失败");
                return new APIResult<APIPaging<List<OrderRecord>>>
                {
                    Code = ResultCode.Error,
                    Message = "获取开单记录列表失败: " + ex.Message
                };
            }
        }

        /// <summary>
        /// 获取开单记录详情
        /// </summary>
        public async Task<APIResult<OrderRecordDetailDto>> GetOrderRecordById(int id)
        {
            try
            {
                var orderRecord = await orderRecordRepository.Getlist()
                    .Include(o => o.HospitalBranch)
                    .Include(o => o.CheckItem)
                    .ThenInclude(c => c.Type)
                    .FirstOrDefaultAsync(o => o.Id == id && !o.IsDeleted);

                if (orderRecord == null)
                {
                    return new APIResult<OrderRecordDetailDto>
                    {
                        Code = ResultCode.Error,
                        Message = "开单记录不存在"
                    };
                }

                var detailDto = new OrderRecordDetailDto
                {
                    Id = orderRecord.Id,
                    PatientName = orderRecord.PatientName,
                    PatientIdCard = orderRecord.PatientIdCard,
                    HospitalBranchName = orderRecord.HospitalBranch?.Name ?? "",
                    ApplicationReason = orderRecord.ApplicationReason,
                    PaymentStatus = orderRecord.PaymentStatus,
                    TotalAmount = orderRecord.TotalAmount,
                    OrderTime = orderRecord.OrderTime,
                    PaymentTime = orderRecord.PaymentTime,
                    CompletedTime = orderRecord.CompletedTime,
                    Items = new List<OrderItemDetailDto>
                    {
                        new OrderItemDetailDto
                        {
                            CheckItemName = orderRecord.CheckItem?.Name ?? "",
                            TypeName = orderRecord.CheckItem?.Type?.Name ?? "",
                            Quantity = orderRecord.ItemCount,
                            UnitPrice = orderRecord.CheckItem?.Price ?? 0,
                            SubTotal = orderRecord.TotalAmount
                        }
                    }
                };

                return new APIResult<OrderRecordDetailDto>
                {
                    Code = ResultCode.Success,
                    Message = "获取开单记录详情成功",
                    Data = detailDto
                };
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "获取开单记录详情失败");
                return new APIResult<OrderRecordDetailDto>
                {
                    Code = ResultCode.Error,
                    Message = "获取开单记录详情失败: " + ex.Message
                };
            }
        }

        /// <summary>
        /// 创建开单申请
        /// </summary>
        public async Task<APIResult<OrderRecord>> CreateOrderRecord(CreateOrderRecordDto createDto)
        {
            try
            {
                // 验证院区是否存在
                var hospitalBranch = await hospitalBranchRepository.Getlist()
                    .FirstOrDefaultAsync(h => h.Id == createDto.HospitalBranchId && !h.IsDeleted);

                if (hospitalBranch == null)
                {
                    return new APIResult<OrderRecord>
                    {
                        Code = ResultCode.Error,
                        Message = "院区不存在"
                    };
                }

                // 验证检查项目是否存在并计算总金额
                decimal totalAmount = 0;
                var orderRecords = new List<OrderRecord>();

                foreach (var item in createDto.Items)
                {
                    var checkItem = await checkItemRepository.Getlist()
                        .FirstOrDefaultAsync(c => c.Id == item.CheckItemId && !c.IsDeleted);

                    if (checkItem == null)
                    {
                        return new APIResult<OrderRecord>
                        {
                            Code = ResultCode.Error,
                            Message = $"检查项目ID {item.CheckItemId} 不存在"
                        };
                    }

                    totalAmount += checkItem.Price * item.Quantity;

                    // 为每个项目创建单独的订单记录
                    var orderRecord = new OrderRecord
                    {
                        HospitalBranchId = createDto.HospitalBranchId,
                        CheckItemId = item.CheckItemId,
                        ItemCount = item.Quantity,
                        TotalAmount = checkItem.Price * item.Quantity,
                        PaymentStatus = "待审核",
                        OrderTime = DateTime.Now,
                        PatientName = createDto.PatientName,
                        PatientIdCard = createDto.PatientIdCard,
                        ApplicationReason = createDto.ApplicationReason,
                        Remarks = $"申请项目：{checkItem.Name} × {item.Quantity}"
                    };

                    orderRecords.Add(orderRecord);
                }

                // 保存所有订单记录
                foreach (var orderRecord in orderRecords)
                {
                    await orderRecordRepository.AddAsyn(orderRecord);
                }

                // 返回第一个订单记录作为代表
                return new APIResult<OrderRecord>
                {
                    Code = ResultCode.Success,
                    Message = "创建开单申请成功",
                    Data = orderRecords.First()
                };
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "创建开单申请失败");
                return new APIResult<OrderRecord>
                {
                    Code = ResultCode.Error,
                    Message = "创建开单申请失败: " + ex.Message
                };
            }
        }

        /// <summary>
        /// 更新支付状态
        /// </summary>
        public async Task<APIResult<bool>> UpdatePaymentStatus(UpdatePaymentStatusDto updateDto)
        {
            try
            {
                var orderRecord = await orderRecordRepository.Getlist()
                    .FirstOrDefaultAsync(o => o.Id == updateDto.OrderRecordId && !o.IsDeleted);

                if (orderRecord == null)
                {
                    return new APIResult<bool>
                    {
                        Code = ResultCode.Error,
                        Message = "开单记录不存在"
                    };
                }

                orderRecord.PaymentStatus = updateDto.PaymentStatus;
                orderRecord.Remarks = updateDto.Remarks;
                orderRecord.UpdatedTime = DateTime.Now;

                // 根据状态设置相应时间
                if (updateDto.PaymentStatus == "已支付")
                {
                    orderRecord.PaymentTime = DateTime.Now;
                }
                else if (updateDto.PaymentStatus == "已完成")
                {
                    orderRecord.CompletedTime = DateTime.Now;
                }

                await orderRecordRepository.Update(orderRecord);

                return new APIResult<bool>
                {
                    Code = ResultCode.Success,
                    Message = "更新支付状态成功",
                    Data = true
                };
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "更新支付状态失败");
                return new APIResult<bool>
                {
                    Code = ResultCode.Error,
                    Message = "更新支付状态失败: " + ex.Message
                };
            }
        }

        /// <summary>
        /// 取消开单申请
        /// </summary>
        public async Task<APIResult<bool>> CancelOrderRecord(int id)
        {
            try
            {
                var orderRecord = await orderRecordRepository.Getlist()
                    .FirstOrDefaultAsync(o => o.Id == id && !o.IsDeleted);

                if (orderRecord == null)
                {
                    return new APIResult<bool>
                    {
                        Code = ResultCode.Error,
                        Message = "开单记录不存在"
                    };
                }

                if (orderRecord.PaymentStatus == "已支付" || orderRecord.PaymentStatus == "已完成")
                {
                    return new APIResult<bool>
                    {
                        Code = ResultCode.Error,
                        Message = "已支付或已完成的订单不能取消"
                    };
                }

                orderRecord.PaymentStatus = "已取消";
                orderRecord.UpdatedTime = DateTime.Now;

                await orderRecordRepository.Update(orderRecord);

                return new APIResult<bool>
                {
                    Code = ResultCode.Success,
                    Message = "取消开单申请成功",
                    Data = true
                };
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "取消开单申请失败");
                return new APIResult<bool>
                {
                    Code = ResultCode.Error,
                    Message = "取消开单申请失败: " + ex.Message
                };
            }
        }

        /// <summary>
        /// 获取院区列表
        /// </summary>
        public async Task<APIResult<List<HospitalBranch>>> GetHospitalBranchList()
        {
            try
            {
                // 首先尝试从数据库获取院区数据
                var hospitalBranches = await hospitalBranchRepository.Getlist()
                    .Where(h => !h.IsDeleted && h.IsEnabled)
                    .OrderBy(h => h.SortOrder)
                    .ToListAsync();

                

                return new APIResult<List<HospitalBranch>>
                {
                    Code = ResultCode.Success,
                    Message = "获取院区列表成功",
                    Data = hospitalBranches
                };
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "获取院区列表失败");

                
                    return new APIResult<List<HospitalBranch>>
                    {
                        Code = ResultCode.Error,
                        Message = "获取院区列表失败: " + ex.Message
                    };
            }
        }

        /// <summary>
        /// 获取检查项目列表
        /// </summary>
        public async Task<APIResult<List<CheckItem>>> GetCheckItemList(int? typeId = null)
        {
            try
            {
                var query = checkItemRepository.Getlist()
                    .Where(c => !c.IsDeleted && c.IsEnabled);

                // 只有当typeId不为null时才添加筛选条件
                if (typeId.HasValue)
                {
                    query = query.Where(c => c.TypeId == typeId.Value);
                }

                var items = await query.ToListAsync();

                return new APIResult<List<CheckItem>>
                {
                    Code = ResultCode.Success,
                    Message = "获取检查项目列表成功",
                    Data = items
                };
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "获取检查项目列表失败");

                return new APIResult<List<CheckItem>>
                {
                    Code = ResultCode.Error,
                    Message = "获取检查项目列表失败: " + ex.Message
                };
            }
        }

        /// <summary>
        /// 获取检查项目类型列表
        /// </summary>
        public async Task<APIResult<List<CheckItemType>>> GetCheckItemTypeList(int? parentId = null)
        {
            try
            {
                var query = checkItemTypeRepository.Getlist()
                    .Where(t => !t.IsDeleted && t.IsEnabled);

                if (parentId.HasValue)
                {
                    query = query.Where(t => t.ParentId == parentId.Value);
                }
                else
                {
                    query = query.Where(t => t.ParentId == null); // 获取一级分类
                }

                return new APIResult<List<CheckItemType>>
                {
                    Code = ResultCode.Success,
                    Message = "获取检查项目类型列表成功",
                    Data = query.ToList().ToList()
                };
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "获取检查项目类型列表失败");

                    return new APIResult<List<CheckItemType>>
                    {
                        Code = ResultCode.Error,
                        Message = "获取检查项目类型列表失败: " + ex.Message
                    };
            }
        }

        /// <summary>
        /// 获取已选项目的详细信息
        /// </summary>
        /// <param name="selectedItemIds">已选项目ID列表</param>
        /// <returns>已选项目的详细信息</returns>
        public async Task<APIResult<List<SelectedItemDetailDto>>> GetSelectedItemsDetail(List<int> selectedItemIds)
        {
            try
            {
                if (selectedItemIds == null || !selectedItemIds.Any())
                {
                    return new APIResult<List<SelectedItemDetailDto>>
                    {
                        Code = ResultCode.Success,
                        Message = "暂无已选项目",
                        Data = new List<SelectedItemDetailDto>()
                    };
                }

                var items = await checkItemRepository.Getlist()
                    .Where(c => selectedItemIds.Contains(c.Id) && !c.IsDeleted && c.IsEnabled)
                    .Include(c => c.Type)
                    .ToListAsync();

                var selectedItems = items.Select(item => new SelectedItemDetailDto
                {
                    Id = item.Id,
                    Name = item.Name,
                    Price = item.Price,
                    TypeName = item.Type?.Name ?? "",
                    TypeCode = item.Type?.Code ?? "",
                    Purpose = item.Purpose,
                    Precautions = item.Precautions
                }).ToList();

                return new APIResult<List<SelectedItemDetailDto>>
                {
                    Code = ResultCode.Success,
                    Message = "获取已选项目详情成功",
                    Data = selectedItems
                };
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "获取已选项目详情失败");

                return new APIResult<List<SelectedItemDetailDto>>
                {
                    Code = ResultCode.Error,
                    Message = "获取已选项目详情失败: " + ex.Message
                };
            }
        }

        /// <summary>
        /// 计算已选项目的总价
        /// </summary>
        /// <param name="selectedItems">已选项目列表</param>
        /// <returns>总价信息</returns>
        public async Task<APIResult<OrderSummaryDto>> CalculateOrderSummary(List<OrderItemDto> selectedItems)
        {
            try
            {
                if (selectedItems == null || !selectedItems.Any())
                {
                    return new APIResult<OrderSummaryDto>
                    {
                        Code = ResultCode.Success,
                        Message = "暂无已选项目",
                        Data = new OrderSummaryDto
                        {
                            TotalItems = 0,
                            TotalAmount = 0,
                            Items = new List<OrderItemSummaryDto>()
                        }
                    };
                }

                var itemIds = selectedItems.Select(s => s.CheckItemId).ToList();
                var items = await checkItemRepository.Getlist()
                    .Where(c => itemIds.Contains(c.Id) && !c.IsDeleted && c.IsEnabled)
                    .Include(c => c.Type)
                    .ToListAsync();

                var orderItems = new List<OrderItemSummaryDto>();
                decimal totalAmount = 0;
                int totalItems = 0;

                foreach (var selectedItem in selectedItems)
                {
                    var item = items.FirstOrDefault(i => i.Id == selectedItem.CheckItemId);
                    if (item != null)
                    {
                        var itemTotal = item.Price * selectedItem.Quantity;
                        totalAmount += itemTotal;
                        totalItems += selectedItem.Quantity;

                        orderItems.Add(new OrderItemSummaryDto
                        {
                            ItemId = item.Id,
                            ItemName = item.Name,
                            ItemType = item.Type?.Name ?? "",
                            UnitPrice = item.Price,
                            Quantity = selectedItem.Quantity,
                            TotalPrice = itemTotal,
                            Unit = GetUnitByType(item.Type?.Code ?? "")
                        });
                    }
                }

                var summary = new OrderSummaryDto
                {
                    TotalItems = totalItems,
                    TotalAmount = totalAmount,
                    Items = orderItems
                };

                return new APIResult<OrderSummaryDto>
                {
                    Code = ResultCode.Success,
                    Message = "计算订单摘要成功",
                    Data = summary
                };
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "计算订单摘要失败");

                return new APIResult<OrderSummaryDto>
                {
                    Code = ResultCode.Error,
                    Message = "计算订单摘要失败: " + ex.Message
                };
            }
        }

        /// <summary>
        /// 根据类型获取单位
        /// </summary>
        /// <param name="typeCode">类型编码</param>
        /// <returns>单位</returns>
        private string GetUnitByType(string typeCode)
        {
            return typeCode?.ToLower() switch
            {
                "medicine" => "剂",
                "examination" => "次",
                "test" => "次",
                _ => "次"
            };
        }
    }
}
